/**
 **************************************************************************************
 * @file    drv_tmailbox.c
 * @brief   Driver for the mailbox between MCU and DSP
 *
 * @author  Aixing.Li
 * @version V2.0.0
 *
 * &copy; 2019 Mobvoi Corporation Ltd. All rights reserved.
 **************************************************************************************
 */

#include "M510reg.h"
#include "drv_mailbox.h"

void mailbox_mcu2dsp_send(uint32_t cmd, uint32_t param0, uint32_t param1, uint32_t param2)
{
    REG_MBOX0_MAIL0 = cmd;
    REG_MBOX0_0x01 = param0;
    REG_MBOX0_0x02 = param1;
    REG_MBOX0_0x03 = param2;
    REG_MBOX0_READY |= 1;
}

void mailbox_mcu2dsp_resp(uint32_t cmd, uint32_t param0, uint32_t param1, uint32_t param2)
{
    REG_MBOX0_MAIL1 = cmd;
    REG_MBOX0_0x05 = param0;
    REG_MBOX0_0x06 = param1;
    REG_MBOX0_0x07 = param2;
}

void mailbox_dsp2mcu_send(uint32_t cmd, uint32_t param0, uint32_t param1, uint32_t param2)
{
    REG_MBOX1_MAIL0 = cmd;
    REG_MBOX1_0x01 = param0;
    REG_MBOX1_0x02 = param1;
    REG_MBOX1_0x03 = param2;
    REG_MBOX1_READY |= 1;
}

void mailbox_dsp2mcu_resp(uint32_t cmd, uint32_t param0, uint32_t param1, uint32_t param2)
{
    REG_MBOX1_MAIL1 = cmd;
    REG_MBOX1_0x05 = param0;
    REG_MBOX1_0x06 = param1;
    REG_MBOX1_0x07 = param2;
}

void mailbox_mcu2dsp_send_until_recv(uint32_t cmd, uint32_t param0, uint32_t param1, uint32_t param2)
{
    uint32_t t = 100000;

    REG_MBOX0_MAIL0 = cmd;
    REG_MBOX0_0x01 = param0;
    REG_MBOX0_0x02 = param1;
    REG_MBOX0_0x03 = param2;
    REG_MBOX0_READY |= 1;
    __asm__("b.nop 5;");
    __asm__("b.nop 5;");
    __asm__("b.nop 5;");
    __asm__("b.nop 5;");
    __asm__("b.nop 5;");
    __asm__("b.nop 5;");
    while ((t--) && (REG_MBOX0_READY & 1))
        __asm__("b.nop 5;");
}

uint32_t mailbox_mcu2dsp_is_busy(void)
{
    return REG_MBOX0_READY & 1;
}

uint32_t mailbox_dsp2mcu_is_busy(void)
{
    return REG_MBOX1_READY & 1;
}

uint32_t mailbox_mcu2dsp_ack_get(uint32_t idx)
{
    return *((volatile uint32_t *)(&REG_MBOX0_MAIL1) + idx);
}

uint32_t mailbox_dsp2mcu_ack_get(uint32_t idx)
{
    return *((volatile uint32_t *)(&REG_MBOX1_MAIL1) + idx);
}

#if !defined(CEVAX2) && !defined(TEAKLITE4)

void mailbox_mcu_isr(void)
{

    if (REG_MBOX1_READY & 1)
    {
        mailbox_mcu_cmd_handler((MailBoxCmd *)&REG_MBOX1_MAIL0);

        REG_MBOX1_CLEAR |= 1;
    }

    if (REG_MBOX1_READY & 2)
    {
        mailbox_mcu_cmd_handler((MailBoxCmd *)&REG_MBOX1_MAIL1);

        REG_MBOX1_CLEAR |= 2;
    }
}

__attribute__((weak)) void mailbox_mcu_cmd_handler(MailBoxCmd *mbc)
{

	uint32_t cmd = mbc->cmd & MAILBOX_CMD_SET_MASK;
	if(mbc->param0 != 0)
	{
		REG_GPIO_0x20 = 0X02;
 		os_printf("[DSP]: mailbox_cmd_handler(%08X, %08X, %08X, %08X)\r\n", mbc->cmd, mbc->param0, mbc->param1, mbc->param2);
	}

}

#else

void mailbox_dsp_isr(void)
{
    if (REG_MBOX0_READY & 1)
    {
        mailbox_dsp_cmd_handler((MailBoxCmd *)&REG_MBOX0_MAIL0);

        REG_MBOX0_CLEAR |= 1;
    }

    if (REG_MBOX0_READY & 0x2)
    {
        mailbox_dsp_cmd_handler((MailBoxCmd *)&REG_MBOX0_MAIL1);

        REG_MBOX0_CLEAR |= 2;
    }
}

#endif
